// 创建类收集依赖
class Depend {
    constructor() {
        // 执行一次
        this.reactiveFns = new Set()
    }
    addDepend(fn) {
        if (fn) {
            this.reactiveFns.add(fn)
        }
    }
    depend() {
        if (reactiveFn) {
            this.reactiveFns.add(reactiveFn)
        }
    }
    notify() {
        this.reactiveFns.forEach(fn => {
            fn()
        })
    }
}

// 创建类
let reactiveFn = null
function watchFn(fn) {
    reactiveFn = fn
    fn()
    reactiveFn = null
}
// 封装一个函数：负责通过obj的key获取对应depend对象
const objMap = new WeakMap()
function getDepend(obj, key) {
    // 1.根据对象obj，找到对应的map对象
    let map = objMap.get(obj)
    if (!map) {
        map = new Map()
        objMap.set(obj, map)
    }
    // 2.根据key，找到对应的denpenf对象
    let dep = map.get(key)
    if (!dep) {
        dep = new Depend()
        map.set(key, dep)
    }
    return dep
}
// 方案一：Object.defineProperty() vue2
function reactive(obj) {
    Object.keys(obj).forEach(key => {
        let value = obj[key]
        Object.defineProperty(obj, key, {
            set: function (newValue) {
                value = newValue
                const dep = getDepend(obj, key)
                dep.notify()
            },
            get: function () {
                const dep = getDepend(obj, key)
                dep.depend()
                return value
            }
        })
    })
    return obj
}

// 业务代码
const obj = reactive({
    name: "ran",
    age: 18,
    height: 180
})
const foo = reactive({
    name: "xiao",
    age: 13,
    height: 150
})
watchFn(function () {
    console.log(obj.name);
    console.log(obj.age);
})

watchFn(function () {
    console.log(obj.age);
    console.log(obj.height);
})
watchFn(function () {
    console.log(obj.height);
    console.log(obj.height);
    console.log(obj.height);
})
console.log("--------------------");
obj.name = "哈哈"
console.log("-----------");
obj.height = 170
console.log("foo===========");
watchFn(function () {
    console.log(foo.name);
    console.log(foo.height);
})
foo.name="嘻嘻"